#!/usr/bin/php
<?
#
# Hjälpscript till webgränsnitt för SFTP-backuper
#######################################


$LOGFILE	= '/var/log/sftp-backup';
$CONFFILE	= '/etc/rdiff-backup-sftp';
$BACKUPLINE	= 'rdiff-backup -v6 -b --force --exclude-special-files --exclude "'.$LOGFILE.'"';
$MOUNTDIR	= '../services/rdiffbackup/sftpmount';

$children = array();
$children_pipes = array();
$shutdown_now = false;


###
# Kör backup
###
function start_backup()
{
	require '../inc/rwINIfile.php';

	global $LOGFILE, $CONFFILE, $BACKUPLINE, $USERNAME, $MOUNTDIR;
	global $children, $children_pipes, $shutdown_now;

	// Läser conffil
	$conf = readINIfile ($CONFFILE, '#');

	// Skapar mounteringspunkt om denna ej finns
	if( !is_dir($MOUNTDIR) ) {
		mkdir($MOUNTDIR, 0700);
	}
	// Skriv datum till logfil
	exec('date > '.$LOGFILE);

	// Montera fjärrplats
	$descriptorspec = array(
		0 => array("pipe", "r"),  // stdin
		1 => array("pipe", "w"),  // stdout
		2 => array("pipe", "w") // stderr
	);
	$children['sshfs'] = proc_open('sshpass sshfs -s -f -o workaround=rename -o reconnect -o sshfs_debug "'.$conf['data']['user'].'@dib1.digitaltbankfack.se:/" "'.$MOUNTDIR.'"', $descriptorspec, $children_pipes['sshfs']);
	if( ! is_resource($children['sshfs']) ) {
		echo "FEL vid programstart (sshfs)\n";
		die();
	}
	fwrite($children_pipes['sshfs'][0], $conf['data']['passwd'] );
	fclose($children_pipes['sshfs'][0]);

	// Tolkar conffil, vilka filer ska backupas?
	if( is_array( $conf['included_files']) ) {
		foreach( $conf['included_files'] AS $line ) {
			$BACKUPLINE = $BACKUPLINE.' --include "'.$line.'"';
		}
	}
		// systeminställningar
	if( isset($conf['data']['include_system'] ) ) {
		  // slapd, användardatabas
		exec('/usr/sbin/slapcat | gzip -9 > /var/backups/slapcat.txt.gz');
		$BACKUPLINE = $BACKUPLINE.' --include "/etc" --include "/var/backups/slapcat.txt.gz"';
	}
		// cyrus-mail
	if( isset($conf['data']['include_mail'] ) ) {
		$BACKUPLINE = $BACKUPLINE.' --include "/var/spool/cyrus" --include "/var/lib/cyrus"';
	}
	if( isset($conf['data']['include_groupware'] ) ) {
		  // mysql, horde
		exec('mysqldump -p`cat /etc/mysql.secret` --all-databases --add-drop-database --add-drop-table --add-locks --allow-keywords --disable-keys --extended-insert --force --lock-tables | gzip -9 > /var/backups/mysqldump.sql.gz');
		$BACKUPLINE = $BACKUPLINE.' --include "/var/backups/mysqldump.sql.gz"';
	}

	// Vänta tills fjärrplatsen är monterad
	$time = 10;
	$mounts = file_get_contents('/proc/mounts');
	while( !preg_match('#^sshfs\#.*digitaltbankfack.* '.$MOUNTDIR.' #m', $mounts) && $time >= 0 ) {
		$time = $time-1;
		//sleep(3);
		$mounts = file_get_contents('/proc/mounts');

		//hitta felmeddelanden
		$read = array( $children_pipes['sshfs'][1], $children_pipes['sshfs'][2] );
		if (false === ($num_changed_streams = stream_select($read, $write = NULL, $except = NULL, 1)))  {
			echo "Fel med strömmar och select\n";
			exit;
		}
		else if ($num_changed_streams > 0) {
			foreach( $read AS $line ) {
				echo fgets($line, 1024);
			}
		}
	}

	sleep(1);
	$mounts = file_get_contents('/proc/mounts');
	// Starta backup
	if( preg_match('#^sshfs\#.*digitaltbankfack.* '.$MOUNTDIR.' #m', $mounts) ) {
		file_put_contents($LOGFILE, "Connected\n", FILE_APPEND);
		echo "Connected\n";
		if( !is_dir($MOUNTDIR.'/bkp') ) {
			mkdir($MOUNTDIR.'/bkp', 0700);
		}
		file_put_contents($LOGFILE, "RUN: /usr/bin/unbuffer $BACKUPLINE --exclude \"**\" / \"$MOUNTDIR/bkp/\"\n", FILE_APPEND);

		//Starta rdiff-backup
		$descriptorspec = array(
			0 => array("pipe", "r"),  // stdin
			1 => array("file", $LOGFILE, "a"),  // stdout
			2 => array("pipe", "w") // stderr
		);
		$children['rdiff'] = proc_open( '/usr/bin/unbuffer '.$BACKUPLINE.' --exclude "**" / "'.$MOUNTDIR.'/bkp/"', $descriptorspec, $children_pipes['rdiff']);
		fclose($children_pipes['rdiff'][0]);
		$running = true;
		while( $running ) {
			$stat = proc_get_status( $children['rdiff'] );
			$running = $stat['running'];

			//hitta felmeddelanden
			$read = array( $children_pipes['sshfs'][1], $children_pipes['sshfs'][2], $children_pipes['rdiff'][2] );
			if (false === ($num_changed_streams = stream_select($read, $write = NULL, $except = NULL, 1)))  {
				echo "Fel med strömmar och select\n";
				exit;
			}
			else if ($num_changed_streams > 0) {
				foreach( $read AS $line ) {
					echo fgets($line, 1024);
				}
			}
		}
		echo "\nAvslutat\n";
		echo "dödar barn\n";
		fclose($children_pipes['rdiff'][2]);
		echo "close: rdiff... ";
		proc_close( $children['rdiff'] );
		echo "done\n";

		if( ($ret = $stat['exitcode']) == 0 ) {
			file_put_contents($LOGFILE, "Remove older than 2M\n", FILE_APPEND);
			exec( 'rdiff-backup -v6 --force --remove-older-than 2M "'.$MOUNTDIR.'/bkp/" >> '.$LOGFILE.' 2>&1' );
		}
		else {
			//$ret = $stat['exitcode'];
			echo "ERROR: return $ret\n";
			file_put_contents($LOGFILE, "ERROR: return $ret\n", FILE_APPEND);
		}
		echo "omonterar\n";
		exec('fusermount -u "'.$MOUNTDIR.'" > /dev/null 2> /dev/null');
		echo "close: sshfs... ";

		if( is_resource( $children['sshfs'] )	) {
			while( !feof( $children_pipes['sshfs'][2] ) ) {
				echo fgets($children_pipes['sshfs'][2], 1024);
			}
		}
		proc_close( $children['sshfs'] );
		echo "done\n";
		file_put_contents($LOGFILE, "Done and disconnected\n", FILE_APPEND);
	}

	// Om montering misslyckades, meddela
	else {
		echo "FEL: lyckades ej montera\n";
		file_put_contents($LOGFILE, "ERROR: mount\n", FILE_APPEND);
	}
}


function shutdown()
{
	echo "The End!\n";
}


declare(ticks = 1);
function sig_handler( $sig_nr ) {
        switch ($sig_nr) {
        case SIGTERM:
        case SIGINT:
		echo "Fick signal: $sig_nr\n";
                exit;
                break;
        default:
                echo "Fick okänd signal: $sig_nr\n";
                break;
        }
}




###############

if( $argc < 2 ) {
	echo "\nSkapat för anrop från webgränsnitt\n";
	echo "backup | fix | list | restore\n";
	die();
}

set_time_limit (0);
register_shutdown_function('shutdown');
pcntl_signal(SIGTERM, 'sig_handler');
pcntl_signal(SIGINT, 'sig_handler');

switch( $argv[1] ) {
case 'backup':
	start_backup();
	break;
case 'fix':
	echo "ej impl\n";
	break;
case 'list':
	echo "ej impl\n";
	break;
case 'restore':
	echo "ej impl\n";
	break;
default:
	echo "\nSkapat för anrop från webgränsnitt\n";
	echo "backup | fix | list | restore\n";
	die();
	break;
}
?>
